// addrspace.h 
//	Data structures to keep track of executing user programs 
//	(address spaces).
//
//	For now, we don't keep any information about address spaces.
//	The user level CPU state is saved and restored in the thread
//	executing the user program (see thread.h).
//
// Copyright (c) 1992-1993 The Regents of the University of California.
// All rights reserved.  See copyright.h for copyright notice and limitation 
// of liability and disclaimer of warranty provisions.

#ifndef ADDRSPACE_H
#define ADDRSPACE_H

#include "copyright.h"
#include "filesys.h"
#include "bitmap.h"
class Semaphore;  
class AddrSpace;
class Thread;
// 添加以上声明，不然编译无法通过
#include "synch.h"

#define UserStackSize		1024 	// increase this as necessary!
#define PidNum          100 

class AddrSpace {
  public:
    AddrSpace(OpenFile *executable);	// Create an address space,
					// initializing it with the program
					// stored in the file "executable"
    ~AddrSpace();			// De-allocate an address space
    // 初始化寄存器
    void InitRegisters();		// Initialize user-level CPU registers,
					// before jumping to user code
    // 当线程切换的时候 保存线程的上下文，但是由于我们在内核线程上进行切换，具体的
    // 上下文保存工作，由内核线程完成
    void SaveState();			// Save/restore address space-specific
    void RestoreState();		// info on a context switch 


    void Print(); // 在为一个应用程序新建一个地址空间后调用该函数，
          //输出该程序的页表（页面与帧的映射关系），显示信息有助于后续程序的调试与开发。

    int getSpaceID();


    void wait(int SpaceId);

    // 将打开的文件加入打开文件表，并返回文件描述符
   int getFileDescriptor(OpenFile* openfile);

    void releaseFileDescriptor(int fileId);
   // 通过文件描述符，返回打开文件指针
   OpenFile* getOpenFile(int fileid);

    // 文件重定向
   void fileRedirect(int fid, OpenFile* openfile);

  static GlobalPageEntry* globalPageTable;   // 全局页表

  static SWAPEntry * SwapTable;

  int swapOut();  // 将页换出

  void swapIn(int virtualPage);
  static BitMap * swapMap;  
  // 定义用户进程标识符
    int pid;
  int childPid[100];
  private:

    // 创建全局的bitmap
    static BitMap * frameMap;    // frameMap 用于分配内存中的空闲帧 
    static BitMap * pidMap;      // 用于分配pid 进程号，每当增加一个用户进程，pidCount就加一
    TranslationEntry *pageTable;	// Assume linear page table translation
					// for now!
    unsigned int numPages;		// Number of pages in the virtual 
					// address space

    

    // 创建全局的信号量数组  用于join时的执行顺序控制
    static Semaphore** joinMutex;

   // 每个进程都有一个打开文件表
    OpenFile* openFileTable[10];
    

};

#endif // ADDRSPACE_H
